package com.android.basic

import android.app.Application
import android.content.pm.PackageManager
import android.os.Build
import android.os.Debug
import android.os.Environment
import android.support.v4.app.NotificationManagerCompat
import java.util.*


/**
 * this is a trick to get a `val` after the onCreate is called
 */
private var _androidApp: AndroidApplication? = null
val androidApp: AndroidApplication by lazy { _androidApp!! }

const val enableMethodTracing = false


open class AndroidApplication : Application() {

  var versionCode = 1
    private set
  var versionName = "1.0"
    private set
  var previousVersionCode = -1
    private set

  /**
   * hebrew may appear as an obsolete ISO code "iw" which needs to be replaced by "he"
   *
   * for spanish, country is also needed
   *
   */
  val language: String
    get() {
      var res = Locale.getDefault().language
      if (res?.isEmpty() == true) {
        res = "en"
      } else if (res == "iw") {
        res = "he"
      } else if ((res == "es" && Locale.getDefault().country.toLowerCase() != "es") || res == "pt" || Locale.getDefault().country.toLowerCase() == "tw") {

        res += "-" + Locale.getDefault().country.toLowerCase()
      }
      return res
    }

  val activityManager
    get() = getSystemService(
      android.content.Context.ACTIVITY_SERVICE
    ) as android.app.ActivityManager

  val notificationManagerCompat get() = NotificationManagerCompat.from(this)

  val alarmManger
    get() = (getSystemService(android.content.Context.ALARM_SERVICE) as android.app.AlarmManager)

  final override fun onCreate() {
    super.onCreate()

    _androidApp = this
    if (isMainProcess()) {
      if (enableMethodTracing) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
          Debug.startMethodTracingSampling(
            Environment.getExternalStorageDirectory().path + "/debug.trace",
            80 * 1024 * 1024,
            10000
          )
        }
      }
      // init this
      onCreateMainProcess()
    }
  }

  open fun onCreateMainProcess() {
    setupRxJavaUncaughtExceptionHandler()
    var a = connectivityReceiver.hashCode()
    val previousVersionCodeSp = PreferenceProperty<Int>(
      defaultPreferenceFn,
      "AndroidApplication.previousVersionCode",
      -1,
      JsonAdapter.intAdapter
    )
    previousVersionCode = previousVersionCodeSp.get()

    try {
      val info = packageManager.getPackageInfo(packageName, 0)
      versionName = info.versionName
      versionCode = info.versionCode

      previousVersionCodeSp.update(versionCode)
    } catch (e: PackageManager.NameNotFoundException) {
      e.printStackTrace()
    }

  }

  open fun printError(throwable: Throwable) {
    Timber.d(throwable)
  }


}

//val networkLogs = ReplaySubject.createWithSize<String>(10000)!!
val networkSessions = ReplaySubject.createWithSize<HttpSession>(10000)

data class HttpSession(val url: String, val content: String)

var current = ArrayList<String>()
//
//fun OkHttpClient.Builder.addDebugInterceptors(): OkHttpClient.Builder =
//  if (BuildConfig.DEBUG) {
//    try {
//      addNetworkInterceptor(StethoInterceptor())
////        // TODO(later) copy the code of HttpLoggingInterceptor, and make this class request-aware
////        addInterceptor(HttpLoggingInterceptor(HttpLoggingInterceptor.Logger {
////          postOnUiThread {
////            //            networkLogs.onNext(it)
////            when {
////              it.startsWith("--> END") -> {
////                if (current.isNotEmpty()) {
////                  val httpSession = HttpSession(current[0], current.joinToString(separator = "\n"))
////                  networkSessions.onNext(httpSession)
////                  current.clear()
////                }
////              }
////              it.startsWith("<-- END") -> {
////                if (current.isNotEmpty()) {
////                  val httpSession = HttpSession(current[0], current.joinToString(separator = "\n"))
////                  networkSessions.onNext(httpSession)
////                  current.clear()
////                }
////              }
////              else -> {
////                current.add(it)
////              }
////            }
////
////          }
////        }).apply { level = HttpLoggingInterceptor.Level.BODY })
//    } catch (e: Throwable) {
//      e.printStackTrace()
//      this
//    }
//  } else {
//    this
//  }

